﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;

namespace SqlCeDriver
{
	/*
		Created just to break up the large driver class. This will take care of all the 
		commands that generate code or show or search SQL source
	*/ 
	class SourcecodeCommandProcessor
	{
		internal SourcecodeCommandProcessor(SqlCeDataSource parent)
		{
			this.dataSource = parent;
		}

		internal String ProcessCommand(DbView.Command command)
		{
			DbViewDriver.IDataSource dataSource = (this.dataSource as DbViewDriver.IDataSource);
			// Command should contain a parameter
			String param = DbView.Command.TableParameterName(0);
			String objectName = command[param]; // view ?

			// [Specialise: override display text generation ]
			if (command.Cmd == DbView.Commands.Cmnd.TableSource) // they want the create table command
			    return this.ScriptTable(dataSource, objectName);

			if (command.Cmd == DbView.Commands.Cmnd.ShowSource)  // generic constion
			{
			    // assume we get a hint from the parameters
			    if (command["TYPE"] == "DATA")
			    {
			        String tableName = command["TABLE"];
			        // overwrite the official place for the object
			        command.AddParam(DbView.Command.TableParameterName(0), tableName);
			        return this.ScriptData(tableName);
			    }
			//    if (Command["TYPE"] == "FK")
			//    {
			//        return ScriptForeignKeys(dataSource, objectName, false, false);
			//    }
			//    if (Command["TYPE"] == "FKALL")
			//    {
			//        return ScriptForeignKeys(dataSource, objectName, true, false);
			//    }
			//    if (Command["TYPE"] == "XFK")
			//    {
			//        return ScriptForeignKeys(dataSource, objectName, false, true);
			//    }
			//    if (Command["TYPE"] == "XFKALL")
			//    {
			//        return ScriptForeignKeys(dataSource, objectName, true, true);
			//    }
			}

			//// default / original look in syscomments
			//String sourceCode = Helper.GetSourceCode(this.m_Source.ConnectionString, objectName);
			//if (sourceCode.Length == 0)
			//    return String.Format(NO_SOURCE_CODE, objectName);
			//return sourceCode;
			return "";
		}

		//// Queries database for source of Views, Stored procedures, Triggers etc.
		//internal String GetSourceCode(DbView.ViewContext context, String objectName)
		//{
		//    //String objectName = context.ViewDef.TableName;
		//    String sourceCode = Helper.GetSourceCode(this.m_Source.ConnectionString, objectName);
		//    if (sourceCode.Length == 0)
		//        return String.Format(NO_SOURCE_CODE, objectName);
		//    return sourceCode;
		//}
		// Searches the source of Views, Stored procedures, Triggers etc. for the search text held in the context
		internal string SearchSourceCommand(DbView.ViewContext context)
		{
		    String searchText = context.Command["SEARCH"]; // what to search ffor
		    String filter = context.FilterString;          // what to filter object names on (rarely used?)
		    String template = SqlCeTemplates.Templates.FetchTemplate(this.dataSource.SqlVersion, context.Command.Cmd);
		    // replace search string using the 
		    template = SqlCeTemplates.Templates.ProcessFilterClause(template, searchText, this.dataSource.IsCaseSensitive);
		    //template = SqlCeTemplates.Templates.ProcessFilterClause(template, filter, this.m_Source.IsCaseSensitive);
		    String commandString = String.Format(template, searchText);
		    return commandString;
		}
		
		public String ScriptData(String tableName)
		{
			//SqlTableSchema schema = this.m_Source.MakeSchemaFor(tableName);
			SqlTableSchema schema = Helper.MakeSchemaFor(tableName, this.dataSource.GetAccessor(), this.dataSource.ConnectionString);
			SqlServerScripter scripter = new SqlServerScripter(tableName, schema);
			DataSet dset = new DataSet();
			DataTable dataTable = new Helper(this.dataSource.GetAccessor()).GenericQuery(this.dataSource.GetConnectionString(), "select * from " + tableName, tableName);
			return scripter.ScriptData(dataTable);
		}

		/////////////////////////////////////////////////////////////////////////
		// helpers
		private String ScriptTable(DbViewDriver.IDataSource source, String tableName)
		{
		    // SqlTableSchema schema = this.m_Source.MakeSchemaFor(tableName);
			SqlTableSchema schema = Helper.MakeSchemaFor(tableName, this.dataSource.GetAccessor(), this.dataSource.ConnectionString);
		    SqlServerScripter scripter = new SqlServerScripter(tableName, schema);
		    return scripter.ScriptCreateTable();
		}

		//private String ScriptForeignKeys(DbViewDriver.IDataSource source, String tableName, bool allTables, bool dropOnly)
		//{
		//    String commandTemplate = SqlCeTemplates.Templates.FetchTemplate(this.m_Source.SqlVersion, DbView.Commands.cmd.ForeignKeys);
		//    String sql = TableCommandProcessor.AddFilterClause(commandTemplate, "", this.m_Source.IsCaseSensitive);
			
		//    DataSet DSet = new DataSet();
		//    Helper.GenericMakeDset(this.m_Source.ConnectionString, sql, tableName, out DSet);
		//    FkScripter scripter = new FkScripter();
		//    scripter.ConfigureTable( DSet.Tables[0], 0, 4, 1, 2, 3); // Sorry
		//    scripter.DisabledCol = 5;
		//    scripter.ReplicationCol = 6;
		//    String script = scripter.ScriptKeys(tableName, allTables, dropOnly);
		//    return script;
		//}

		//private String ScriptData(DbViewDriver.IDataSource source, String tableName)
		//{
		//    SqlTableSchema schema = m_Source.MakeSchemaFor(tableName);
		//    SqlServerScripter Scripter = new SqlServerScripter(tableName, schema);
		//    DataSet DSet = new DataSet();
		//    Helper.GenericMakeDset(this.m_Source.ConnectionString, "select * from "+tableName, tableName, out DSet);
		//    DataTable dataTable = DSet.Tables[0];
			
		//    return Scripter.ScriptData(dataTable);
		//}
		
		//private String GenerateTableClass(DbViewDriver.IDataSource source, String tableName)
		//{
		//    SqlTableSchema schema = m_Source.MakeSchemaFor(tableName);
		//    LinqTableGenerator Scripter = new LinqTableGenerator(tableName, schema);
		//    return Scripter.GenerateCode(source.ConnectionString);
		//}

		//// Suspect this is unused
		//private String ScriptSynchContents(DbViewDriver.IDataSource source, String tableName, DbView.ConnectionInfo refreshSourceConnInfo)
		//{
		//    SqlTableSchema schema = m_Source.MakeSchemaFor(tableName);
		//    SqlServerScripter Scripter = new SqlServerScripter(tableName, schema);
		//    SqlScriptingHelper scriptHelper = new SqlScriptingHelper(tableName, schema);
		//    return Scripter.ScriptRowsetRefresh(tableName, refreshSourceConnInfo, scriptHelper);
		//}

		//String DependencyTree(DbView.Command Command, String objectName)
		//{
		//    String template = SqlCeTemplates.Templates.FetchExtensionTemplate(this.m_Source.SqlVersion, Command, Command.Name);
		//    String sql = String.Format(template, objectName);
		//    String sourceCode = Helper.DocFromDset(this.m_Source.ConnectionString, sql, 0, true);
		//    sourceCode = String.Format("{0}\n{1}", objectName, sourceCode);
		//    return sourceCode;
		//}

		//// tries to fish out the last SQL executed by a process. 
		//private string LastSqlFor(string processId)
		//{
		//    String sql = String.Format("DBCC inputbuffer({0})", processId);
		//    DataSet dset;
		//    Helper.GenericMakeDset(this.m_Source.ConnectionString, sql, "SQL", out dset);
		//    String sourceCode = "Cannot find the information";
		//    // Checking that whats returned is expected.
		//    if (dset.Tables.Count > 0)
		//        if (dset.Tables[0].Rows.Count > 0)
		//            if (dset.Tables[0].Columns.Count > 2)
		//                sourceCode = dset.Tables[0].Rows[0][2].ToString();
		//    return sourceCode;
		////}

		SqlCeDataSource dataSource;

		const String NO_SOURCE_CODE = @"
/*
	Could not find source for {0}.

	This is either because the object does not exist in the database or the connection
	you are using does not have permission to access the source.
*/
";
	}
}
